/**
 * 监控和诊断外键约束错误
 */

import { PrismaClient } from '@prisma/client'

const prisma = new PrismaClient()

async function monitorForeignKeyErrors() {
  console.log('🔍 外键约束错误监控和诊断...\n')

  try {
    // 1. 检查所有用户ID
    console.log('👥 检查用户表:')
    const users = await prisma.user.findMany({
      select: {
        id: true,
        email: true,
        name: true,
        role: true,
        _count: {
          select: {
            tools: true,
            reviews: true,
            favorites: true
          }
        }
      },
      orderBy: { createdAt: 'desc' }
    })

    console.log(`   总用户数: ${users.length}`)
    users.forEach((user, index) => {
      console.log(`   ${index + 1}. ${user.name} (${user.email}) - ${user.role}`)
      console.log(`      ID: ${user.id}`)
      console.log(`      工具数: ${user._count.tools}, 评价数: ${user._count.reviews}, 收藏数: ${user._count.favorites}`)
    })

    // 2. 检查工具表中的孤立记录
    console.log('\n🔧 检查工具表中的外键引用:')

    // 获取所有工具并检查用户是否存在
    const allTools = await prisma.tool.findMany({
      select: {
        id: true,
        title: true,
        userId: true
      }
    })

    const toolsWithInvalidUsers = []
    for (const tool of allTools) {
      const userExists = await prisma.user.findUnique({
        where: { id: tool.userId },
        select: { id: true }
      })
      if (!userExists) {
        toolsWithInvalidUsers.push(tool)
      }
    }

    if (toolsWithInvalidUsers.length > 0) {
      console.log(`   ❌ 发现 ${toolsWithInvalidUsers.length} 个工具引用了不存在的用户:`)
      toolsWithInvalidUsers.forEach((tool, index) => {
        console.log(`   ${index + 1}. 工具: ${tool.title}`)
        console.log(`      工具ID: ${tool.id}`)
        console.log(`      引用的用户ID: ${tool.userId}`)
      })
    } else {
      console.log('   ✅ 所有工具都正确引用了存在的用户')
    }

    // 3. 检查评价表中的外键引用
    console.log('\n⭐ 检查评价表中的外键引用:')

    const allReviews = await prisma.review.findMany({
      select: {
        id: true,
        userId: true,
        toolId: true,
        rating: true
      }
    })

    const reviewsWithInvalidRefs = []
    for (const review of allReviews) {
      const userExists = await prisma.user.findUnique({
        where: { id: review.userId },
        select: { id: true }
      })
      const toolExists = await prisma.tool.findUnique({
        where: { id: review.toolId },
        select: { id: true }
      })
      if (!userExists || !toolExists) {
        reviewsWithInvalidRefs.push(review)
      }
    }

    if (reviewsWithInvalidRefs.length > 0) {
      console.log(`   ❌ 发现 ${reviewsWithInvalidRefs.length} 个评价引用了不存在的记录:`)
      reviewsWithInvalidRefs.forEach((review, index) => {
        console.log(`   ${index + 1}. 评价ID: ${review.id}`)
        console.log(`      用户ID: ${review.userId}`)
        console.log(`      工具ID: ${review.toolId}`)
        console.log(`      评分: ${review.rating}`)
      })
    } else {
      console.log('   ✅ 所有评价都正确引用了存在的用户和工具')
    }

    // 4. 检查收藏表中的外键引用
    console.log('\n💖 检查收藏表中的外键引用:')

    const allFavorites = await prisma.favorite.findMany({
      select: {
        id: true,
        userId: true,
        toolId: true
      }
    })

    const favoritesWithInvalidRefs = []
    for (const favorite of allFavorites) {
      const userExists = await prisma.user.findUnique({
        where: { id: favorite.userId },
        select: { id: true }
      })
      const toolExists = await prisma.tool.findUnique({
        where: { id: favorite.toolId },
        select: { id: true }
      })
      if (!userExists || !toolExists) {
        favoritesWithInvalidRefs.push(favorite)
      }
    }

    if (favoritesWithInvalidRefs.length > 0) {
      console.log(`   ❌ 发现 ${favoritesWithInvalidRefs.length} 个收藏引用了不存在的记录:`)
      favoritesWithInvalidRefs.forEach((favorite, index) => {
        console.log(`   ${index + 1}. 收藏ID: ${favorite.id}`)
        console.log(`      用户ID: ${favorite.userId}`)
        console.log(`      工具ID: ${favorite.toolId}`)
      })
    } else {
      console.log('   ✅ 所有收藏都正确引用了存在的用户和工具')
    }

    // 5. 测试工具创建功能
    console.log('\n🧪 测试工具创建功能:')
    
    if (users.length > 0) {
      const testUser = users[0]
      console.log(`   使用测试用户: ${testUser.name} (${testUser.id})`)
      
      try {
        // 创建测试工具
        const testTool = await prisma.tool.create({
          data: {
            title: '外键测试工具',
            description: '用于测试外键约束的工具',
            url: 'https://example.com/fk-test',
            categoryId: '1',
            userId: testUser.id,
            status: 'PENDING',
            isDeployed: false,
            deployPath: null,
            originalFile: ''
          }
        })
        
        console.log(`   ✅ 工具创建成功`)
        console.log(`   工具ID: ${testTool.id}`)
        console.log(`   工具标题: ${testTool.title}`)
        console.log(`   用户ID: ${testTool.userId}`)
        
        // 验证工具确实创建了
        const createdTool = await prisma.tool.findUnique({
          where: { id: testTool.id },
          include: {
            user: {
              select: { id: true, name: true, email: true }
            }
          }
        })
        
        if (createdTool && createdTool.user) {
          console.log(`   ✅ 工具与用户关联正确`)
          console.log(`   关联用户: ${createdTool.user.name} (${createdTool.user.email})`)
        } else {
          console.log(`   ❌ 工具与用户关联失败`)
        }
        
        // 清理测试数据
        await prisma.tool.delete({ where: { id: testTool.id } })
        console.log(`   🧹 测试数据已清理`)
        
      } catch (error: any) {
        console.log(`   ❌ 工具创建失败: ${error.message}`)
        if (error.code === 'P2003') {
          console.log(`   这是外键约束错误！`)
          console.log(`   错误详情:`, error.meta)
        }
      }
    } else {
      console.log('   ⚠️ 没有用户可用于测试')
    }

    // 6. 提供修复建议
    console.log('\n💡 外键约束错误预防建议:')
    console.log('   1. 确保用户在创建工具前已经登录')
    console.log('   2. 验证前端发送的用户ID确实存在于数据库中')
    console.log('   3. 使用认证中间件确保用户ID的一致性')
    console.log('   4. 在创建关联记录前先验证父记录存在')
    console.log('   5. 定期运行此监控脚本检查数据完整性')

    console.log('\n🎉 外键约束监控完成!')

  } catch (error) {
    console.error('\n❌ 监控失败:', error)
  } finally {
    await prisma.$disconnect()
  }
}

// 运行监控
if (require.main === module) {
  monitorForeignKeyErrors()
    .then(() => {
      console.log('\n✨ 监控完成!')
      process.exit(0)
    })
    .catch((error) => {
      console.error('监控失败:', error)
      process.exit(1)
    })
}

export { monitorForeignKeyErrors }
